package com.xxadmin.common.util.clone;

import org.springframework.beans.BeanUtils;
import org.springframework.beans.BeanWrapper;
import org.springframework.beans.BeanWrapperImpl;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
 * 属性复制工具类
 *
 * @author chenming
 * @date:2018/4/23
 */
public class CopyUtils {

    /**
     * 集合属性复制
     *
     * @param source 复制资源
     * @param targetClass  目标类Class
     *
     */
    public static <T> List<T> copyList(List source,Class targetClass){
        if(source != null && source.size() > 0 && targetClass != null){
            List<T> targetList = new ArrayList<T>(source.size());

            T target = null;
            for(int i = 0 , j = source.size() ; i < j ; i++){
                try {
                    target = (T) targetClass.newInstance();
                    BeanUtils.copyProperties(source.get(i), target);
                } catch (Exception e) {
                    return null;
                }
                targetList.add(target);
            }

            return targetList;
        }

        return null;
    }

    /**
     * 集合属性复制 忽略空属性值
     *
     * @param source 资源
     * @param targetClass  目标类Class
     */
    public static <T> List<T> copyListIgnoreNull(List source,Class targetClass){
        if(source != null && source.size() > 0 && targetClass != null){
            List<T> targetList = new ArrayList<T>(source.size());

            T target = null;
            for(int i = 0 , j = source.size() ; i < j ; i++){
                try {
                    target = (T) targetClass.newInstance();
                    BeanUtils.copyProperties(source.get(i), target,getNullPropertyNames(source.get(i)));
                } catch (Exception e) {
                    return null;
                }
                targetList.add(target);
            }

            return targetList;
        }

        return null;
    }


    /**
     * 进行Bean复制
     *
     * @param source 资源
     * @param targetClass 目标类Class
     */
    public static <T extends Object> T copyBean(Object source,Class targetClass) {
        T target = null;
        if (source != null) {
            try {
                target = (T) targetClass.newInstance();

                BeanUtils.copyProperties(source, target);
            } catch (Exception e) {
            }
            return target;
        }

        return null;
    }

    /**
     * 进行Bean属性值复制
     *
     * @param source
     * @param target
     * @return
     */
    public static void copyBean(Object source,Object target){
        if(source != null && target != null){
            try {
                BeanUtils.copyProperties(source,target);
            }catch (Exception e) {
            }
        }
    }

    /**
     * 进行Bean复制，忽略空属性值
     *
     */
    public static <T extends Object> T copyBeanIgnoreNull(Object source,Class targetClass) {
        T target = null;
        if (source != null) {
            try {
                target = (T) targetClass.newInstance();

                BeanUtils.copyProperties(source, target,getNullPropertyNames(source));
            } catch (Exception e) {
                return null;
            }
            return target;
        }

        return null;
    }

    /**
     * 进行Bean复制，忽略空属性值
     *
     */
    public static void copyBeanIgnoreNull(Object source,Object target){
        if(source != null && target != null){
            try {
                BeanUtils.copyProperties(source, target,getNullPropertyNames(source));
            }catch (Exception e) {
            }
        }
    }


    /**
     * 获取value为null的属性值
     *
     */
    private static String[] getNullPropertyNames (Object source) {
        if(source == null){
            return null;
        }

        final BeanWrapper src = new BeanWrapperImpl(source);
        java.beans.PropertyDescriptor[] pds = src.getPropertyDescriptors();

        Set<String> emptyNames = new HashSet<String>();
        for(java.beans.PropertyDescriptor pd : pds) {
            Object srcValue = src.getPropertyValue(pd.getName());
            if(srcValue == null) {
                emptyNames.add(pd.getName());
            }
        }
        String[] result = new String[emptyNames.size()];
        return emptyNames.toArray(result);
    }
}
